/****************/
/* Jiahui Shi	*/
/* 05/28/2011	*/
/* CS 244B	*/
/* Spring 2011	*/
/****************/
#ifndef PROTOCOL_H
#define PROTOCOL_H

#define ADD_SERVER_REQUEST_TYPE  0x00
#define ADD_SERVER_RESPONSE_TYPE 0X01
#define OPEN_FILE_REQUEST_TYPE   0x10
#define OPEN_FILE_RESPONSE_TYPE  0X11
#define WRITE_TYPE               0X20
#define PRECOMMIT_REQUEST_TYPE   0x30
#define PRECOMMIT_RESPONSE_TYPE  0X31
#define COMMIT_REQUEST_TYPE      0x40
#define COMMIT_RESPONSE_TYPE     0X41
#define CLOSE_REQUEST_TYPE       0X50
#define CLOSE_RESPONSE_TYPE      0X51

#define HEADER_LEN 12

#define MAZEGROUP       0xe0010101

#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/stat.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <signal.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <assert.h>
#include <pthread.h>
#include <X11/Xlib.h>

typedef struct sockaddr_in Sockaddr;
typedef struct {
  in_addr_t addr;
  uint8_t active;
} ServerType;

/*---- pack types ----*/
typedef struct {
  uint32_t seqnum; // sequence number
  uint16_t type; // descriptor
  uint16_t checksum;
  uint32_t paylen; // payload length
}__attribute__ ((__packed__)) PacketHeader;

typedef struct {
  PacketHeader header;
  char body[32];
}__attribute__ ((__packed__)) ShortPacket;

typedef struct {
  PacketHeader header;
  char body[640];
}__attribute__ ((__packed__)) LongPacket;

typedef struct {
  in_addr_t ip;
} AddServerRequestPack;


typedef struct {
	ShortPacket	*eventDetail;	/* for incoming data */
	Sockaddr	eventSource;
} MWEvent;


extern Sockaddr *resolveHost(register char *name);
extern void NextEvent(MWEvent *event, int socket);
extern void netInit(Sockaddr *myAddr, uint32_t* my_socket, Sockaddr* groupAddr, int portNum);
extern uint16_t fillChecksum(LongPacket* pack);
extern uint8_t checkSumRight(ShortPacket pack);

/* Use this socket address to send packets to the multi-cast group. */
#endif